#include "SalesmanEnvironment.h"
#include "SalesmanChromosomeFactory.h"
#include "SalesmanGreedyChromosomeFactory.h"
#include "Chromosome.h"

#include <QTime>

#include "parameters.h"

SalesmanEnvironment::SalesmanEnvironment(int _populationSize,
                                 SalesmanData _salesmanData, bool _greedyStart) :
                    AbstractEnvironment(_populationSize),
                    salesmanData(_salesmanData),
                    greedyStart(_greedyStart)
{
    TRACE_FUNC_ENTRY

    //createPrimaryGenaration();

    TRACE_FUNC_EXIT
}

SalesmanEnvironment::~SalesmanEnvironment()
{
    TRACE_FUNC
}

void SalesmanEnvironment::fitnessFunction(Chromosome& chrom)
{
    TRACE_FUNC_ENTRY
    double fitness = 0.0;

    //qDebug() << chrom.size() << " " << chrom;
    //qDebug() << "@" << salesmanData;

    for(int i=0;i<chrom.size()-1;++i)
    {
        fitness += salesmanData.distance(chrom.at(i).toInt(), chrom.at(i+1).toInt());
        //qDebug() << salesmanData.distanceArr[chrom.at(i).toInt()][chrom.at(i+1).toInt()];
    }

    //qDebug() << salesmanData.distanceArr[chrom.at(chrom.size()-1).toInt()][chrom.at(0).toInt()];
    //TODO check that
    fitness += salesmanData.distance(chrom.at(chrom.size()-1).toInt(), chrom.at(0).toInt());

    chrom.setFitness(-fitness);//TODO
    TRACE_FUNC_EXIT
}

void SalesmanEnvironment::createPrimaryGenaration()
{
    int chromosomeLength = 0;

    chromosomeLength = salesmanData.size();

    qDebug() << "chromosomeLength: " << chromosomeLength;

    if(greedyStart)
        chromosomeFactory = new SalesmanGreedyChromosomeFactory(chromosomeLength, salesmanData);
    else
        chromosomeFactory = new SalesmanChromosomeFactory(chromosomeLength);

    AbstractEnvironment::createPrimaryGenaration();
    //createPopulation();

    if(greedyStart)
    {
        delete chromosomeFactory;
        chromosomeFactory = new SalesmanChromosomeFactory(chromosomeLength);
    }
}

QString SalesmanEnvironment::decodeChromosome(const Chromosome& chrom)
{
    qDebug() << "QString SalesmanEnvironment::decodeChromosome(const Chromosome& chrom)";
    QString ret("");

    ret += chrom.toString() + "\n";

    for(int i=0;i<chrom.size();++i)
    {
        ret += salesmanData.getCity(chrom.at(i).toInt()).getName() + " -> ";
    }
    ret += salesmanData.getCity(chrom.at(0).toInt()).getName() + "\n";


    return ret;
}

void SalesmanEnvironment::setGreedyStart(bool _greedyStart)
{
    greedyStart = _greedyStart;
}

void SalesmanEnvironment::setSalesmanData(SalesmanData _salesmanData)
{
    salesmanData = _salesmanData;
}
